#include <arpa/inet.h>
#include <cstring>
#include <fcntl.h>
#include <iostream>
#include <netinet/in.h>
#include <string>
#include <thread>
#include <unistd.h>

#define SERVER_IP "127.0.0.1"
#define PORT      6666

// 函数原型
void receiveMessages(int client_socket);

int main()
{
    // 创建客户端套接字
    int client_socket = socket(AF_INET, SOCK_STREAM, 0);
    if ( client_socket == -1 ) {
        std::cerr << "Failed to create client socket" << std::endl;
        return 1;
    }

    // 设置服务器地址结构
    sockaddr_in server_addr{};
    server_addr.sin_family      = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
    server_addr.sin_port        = htons(PORT);

    // 连接服务器
    if ( connect(client_socket, reinterpret_cast<sockaddr*>(&server_addr), sizeof(server_addr)) == -1 ) {
        std::cerr << "Failed to connect to server" << std::endl;
        close(client_socket);
        return 1;
    }

    // 接收并打印服务器发送的消息
    char    buffer[1024];
    ssize_t bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
    if ( bytes_received == -1 ) {
        std::cerr << "Failed to receive message from server" << std::endl;
        close(client_socket);
        return 1;
    }

    buffer[bytes_received] = '\0';
    std::cout << buffer << std::endl;

    // 创建接收消息的线程
    std::thread receive_thread(receiveMessages, client_socket);

    // 发送消息给服务器
    while ( true ) {
        std::string message;
        std::getline(std::cin, message);

        ssize_t bytes_sent = send(client_socket, message.c_str(), message.size(), 0);
        if ( bytes_sent == -1 ) {
            std::cerr << "Failed to send message to server" << std::endl;
            close(client_socket);
            return 1;
        }
    }

    return 0;
}

// 接收服务器消息并打印的函数
void receiveMessages(int client_socket)
{
    while ( true ) {
        char    buffer[1024];
        ssize_t bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
        if ( bytes_received == -1 ) {
            std::cerr << "Failed to receive message from server" << std::endl;
            close(client_socket);
            exit(1);
        }
        else if ( bytes_received == 0 ) {
            std::cerr << "Server closed connection" << std::endl;
            close(client_socket);
            exit(1);
        }

        buffer[bytes_received] = '\0';
        std::cout << buffer << std::endl;
    }
}
